package work.jame.blog.service.impl;

import cn.hutool.core.util.RandomUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import work.jame.blog.framework.constant.FileConstant;
import work.jame.blog.framework.constant.HttpHeaderConstant;
import work.jame.blog.framework.exception.db.UpdateDataBaseException;
import work.jame.blog.framework.exception.file.FileTypeException;
import work.jame.blog.framework.result.Result;
import work.jame.blog.framework.result.ServerStatusCode;
import work.jame.blog.framework.utils.FileUtils;
import work.jame.blog.framework.utils.http.WebUtils;
import work.jame.blog.service.FileService;
import work.jame.blog.service.UserService;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Objects;


/**
 * @author : Jame
 * @date : 2023-05-17 14:39
 **/
@Service
public class FileServiceImpl implements FileService {

    @Autowired
    private UserService userService;


    private static final Logger LOGGER = LoggerFactory.getLogger(FileServiceImpl.class);

    private static final String DOT = ".";

    static {
        //检查对应的文件夹是否已经存在
        FileUtils.checkFolderExistOrCreate(FileConstant.ARTICLE_IMG_BASE_PATH);
        FileUtils.checkFolderExistOrCreate(FileConstant.USER_AVATAR_BASE_PATH);
    }

    private String uploadImg(String filePath, MultipartFile multipartFile) {
        if (Objects.isNull(multipartFile)) {
            return null;
        }
        String fileType = FileUtils.getFileType(multipartFile.getOriginalFilename());

        if (!StringUtils.hasText(fileType)) {
            return null;
        }
        if (!fileType.equals("jpg") && !fileType.equals("jpeg") && !fileType.equals("png")) {
            throw new FileTypeException("请传入图片类型的文件,支持jpg/jpeg,png");
        }
        String fileName = RandomUtil.randomString(5) + System.currentTimeMillis() + DOT + fileType;
        String fileFullPath = filePath + fileName;
        byte[] bytes;
        try {
            //压缩到200kb
            bytes = FileUtils.compressPicForScale(multipartFile.getBytes(), 200);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (bytes.length == 0) {
            return null;
        }
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);

        try {
            BufferedImage image = ImageIO.read(in);
            //有问题的图片例如强转过格式,通过read读出来就是null
            if (Objects.isNull(image)) {
                //todo 自定义异常
                throw new RuntimeException("图片读取错误");
            }
            File file = new File(fileFullPath);
            ImageIO.write(image, fileType, file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return fileName;
    }


    private void getImg(String filePath, String fileName) {
        HttpServletResponse response = WebUtils.getResponse();
        File file = new File(filePath + fileName);
        if (!file.exists() || !file.canRead()) {
            Result<?> result = Result.create(null, ServerStatusCode.FAIL, "获取图片失败");
            WebUtils.respondResult(response, result);
        }
        try (FileInputStream inputStream = new FileInputStream(file)) {
            int length = inputStream.available();
            byte[] data = new byte[length];
            response.setContentLength(length);
            String name = file.getName();
            String fileType = FileUtils.getFileType(name);
            response.setContentType(HttpHeaderConstant.CONTENT_TYPE_IMAGE + fileType);
            int read = inputStream.read(data);
            OutputStream toClient = response.getOutputStream();
            toClient.write(data);
            toClient.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String uploadArticleImg(MultipartFile multipartFile) {
        return uploadImg(FileConstant.ARTICLE_IMG_BASE_PATH, multipartFile);
    }

    @Override
    public String uploadUserAvatar(MultipartFile multipartFile) {
        String fileName = uploadImg(FileConstant.USER_AVATAR_BASE_PATH, multipartFile);
        if (!userService.updateUserAvatar(fileName)) {
            throw new UpdateDataBaseException("更新头像失败");
        }
        return fileName;

    }

    @Override
    public void getArticleImg(String fileName) {
        getImg(FileConstant.ARTICLE_IMG_BASE_PATH, fileName);
    }

    @Override
    public void getUserAvatar(String fileName) {
        getImg(FileConstant.USER_AVATAR_BASE_PATH, fileName);
    }
}
